use crate::app::server::conn;
use crate::app::server::handle;
use std::io;
use std::net::{TcpStream, TcpListener};
use std::sync::{Arc, RwLock};

pub struct ServerEntity {
    pub addr_port: String,
    pub handers: Arc<RwLock<handle::HandlerManage>>,
    pub hook: Arc<dyn handle::ConnHook + Send + 'static>,
    pub coon_list: Vec<TcpStream>,
    pub lister:Option<TcpListener>,
}

impl ServerEntity {
    pub fn new(ap: String) -> ServerEntity {
        ServerEntity {
            addr_port: ap,
            handers: Arc::new(RwLock::new(handle::HandlerManage::new())),
            hook: Arc::new(handle::ConnHookDefault {}),
            coon_list: vec![],
            lister:None,
        }
    }
    pub fn regist_call<F>(&mut self, status: u16, call: Arc<F>)
    where
        F: handle::Handle + Send + 'static,
    {
        // self.handers.register(status, call);
        match self.handers.write() {
            Err(e) => {
                log_error_ln!("regist_call:注册回调时锁错误 {}", e.to_string());
            }
            Ok(mut o) => {
                o.register(status, call);
            }
        }
    }
    pub fn run(&mut self) -> io::Result<()> {
        let res = std::net::TcpListener::bind(self.addr_port.as_str());
        let lister = match res {
            Err(e) => return Err(e),
            Ok(o) => o,
        };
        self.lister = Some(lister.try_clone().expect("克隆错误"));
        loop {
            match lister.accept() {
                Ok((sock, addr)) => {
                    let handle_lock = Arc::clone(&self.handers);
                    let hook_lock = Arc::clone(&self.hook);
                    match conn::ConnEntity::new(sock, addr, handle_lock, hook_lock) {
                        Err(e) => {
                            log_error_ln!("socket转换错误:{}", e.to_string());
                        }
                        Ok(mut o) => {
                            tokio::spawn(async move { o.run().await });
                        }
                    }
                }
                Err(e) => {
                    log_error_ln!("接受新连接错误：{}", e.to_string());
                }
            }
        }
        //Ok(())
    }
}
